package org.activision.net.update;

import org.activision.Engine;
import org.activision.model.World;
import org.activision.model.npc.Npc;
import org.activision.model.player.Player;

public class EntityUpdate implements Runnable {

	private final static boolean[] playerUpdates = new boolean[2048];

	public void run() {
		while (true) {
			try{ 
			Engine.getWorldExecutor().purge();
			Engine.getEntityExecutor().purge();
			long startLoopTime = System.currentTimeMillis();
			for (Npc npc : World.getNpcs()) {
				if (npc == null)
					continue;
				synchronized (npc) {
					npc.getWalk().getNextEntityMovement();
				}
			}
			for (Player player : World.getPlayers()) {
				if (player == null)
					continue;
				synchronized (player) {
					if (player.isOnline()) {
						player.getWalk().getNextEntityMovement();
					}
				}
			}
			for (Player player : World.getPlayers()) {
				if (player == null)
					continue;
				synchronized (player) {
					if (player.isOnline()) {
						if (!player.isDead()) {
							player.getCombat().processDelays();
							player.getCombat().processAttack();
							player.getCombat().processPrayerBeforeHit();
							player.getCombat().processHit();
							player.getCombat().processPrayerAfterHit();
						}
					}
				}
			}

			for (int index = 0; index < 2048; index++) {
				Player player = World.getPlayers().get(index);
				if (player == null)
					continue;
				synchronized (player) {
					if (player.isOnline()) {
						player.processQueuedHits();
						playerUpdates[index] = player.getMask().isUpdateNeeded();
					}
				}
			}
			for (Player player : World.getPlayers()) {
				if (player == null)
					continue;
				synchronized (player) {
					if (player.isOnline()) {
						player.getGpi().sendUpdate();
						player.getGni().sendUpdate();
					}
				}
			}
			for (Npc npc : World.getNpcs()) {
				if (npc == null)
					continue;
				synchronized (npc) {
					npc.getMask().reset();
				}
			}
			for (int index = 0; index < 2048; index++) {
				if (!playerUpdates[index])
					continue;
				playerUpdates[index] = false;
				Player player = World.getPlayers().get(index);
				if (player == null)
					continue;
				synchronized (player) {
					if (player.isOnline()) {
						player.getMask().reset();
					}
				}
			}
			long sleepTime = startLoopTime+600-System.currentTimeMillis();
			if(sleepTime > 0) {
				try {
					Thread.sleep(sleepTime);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			}catch(Error e) {
				e.printStackTrace();
			}
		}
	}

	public static final boolean[] getPlayerUpdates() {
		return playerUpdates;
	}

}